/*
 * Copyright 1999-2018 Alibaba Group Holding Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *      http://www.apache.org/licenses/LICENSE-2.0
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import React from 'react';
import PropTypes from 'prop-types';
import {request} from '../../../globalLib';
import {Dialog, Form, Input, Select, Message, ConfigProvider} from '@alifd/next';
import {DIALOG_FORM_LAYOUT, METADATA_SEPARATOR, METADATA_ENTER} from './constant';
import MonacoEditor from 'components/MonacoEditor';
import {replaceEnter, processMetaData} from 'utils/nacosutil';

@ConfigProvider.config

class EditServiceDialog extends React.Component {
  static displayName = 'EditServiceDialog';

  static propTypes = {
    queryServiceList: PropTypes.func,
    getServiceDetail: PropTypes.func,
    locale: PropTypes.object,
  };

  constructor(props) {
    super(props);
    this.state = {
      isCreate: false,
      editService: {},
      editServiceDialogVisible: false,
      errors: {name: {}, protectThreshold: {}},
    };
    this.show = this.show.bind(this);
  }

  show(_editService = {}) {
    let editService = _editService;
    const {metadata = {}, name} = editService;
    if (Object.keys(metadata).length) {
      editService.metadataText = processMetaData(METADATA_ENTER)(metadata);
    }
    this.setState({editService, editServiceDialogVisible: true, isCreate: !name});
  }

  hide() {
    this.setState({editServiceDialogVisible: false});
  }

  validator(field) {
    const {locale = {}} = this.props;
    const errors = Object.assign({}, this.state.errors);
    const helpMap = {
      name: locale.serviceNameRequired,
      protectThreshold: locale.protectThresholdRequired,
    };
    if (field.protectThreshold === 0) {
      field.protectThreshold = '0';
    }
    for (const key in field) {
      if (!field[key]) {
        errors[key] = {validateState: 'error', help: helpMap[key]};
        this.setState({errors});
        return false;
      }
    }
    return true;
  }

  onConfirm() {
    const {isCreate} = this.state;
    const editService = Object.assign({}, this.state.editService);
    const {name, protectThreshold, groupName, metadataText = '', selector} = editService;
    if (!this.validator({name, protectThreshold})) return;
    request({
      method: isCreate ? 'POST' : 'PUT',
      url: 'v1/ns/service',
      data: {
        serviceName: name,
        groupName: groupName || 'DEFAULT_GROUP',
        protectThreshold,
        metadata: replaceEnter(METADATA_SEPARATOR)(metadataText),
        selector: JSON.stringify(selector),
      },
      dataType: 'text',
      beforeSend: () = > this.setState({loading: true}),
      success
  :
    res =
  >
    {
      if (res !== 'ok') {
        Message.error(res);
        return;
      }
      if (isCreate) {
        this.props.queryServiceList();
      } else {
        this.props.getServiceDetail();
      }
    }
  ,
    error: res =
  >
    Message.error(res.responseText || res.statusText),
      complete
  :
    () =
  >
    this.setState({loading: false}),
  })
    ;
    this.hide();
  }

  onChangeCluster(changeVal) {
    const resetKey = ['name', 'protectThreshold'];
    const {editService = {}} = this.state;
    const errors = Object.assign({}, this.state.errors);
    resetKey.forEach(key = > {
      if(changeVal[key]
  )
    {
      errors[key] = {};
      this.setState({errors});
    }
  })
    ;
    this.setState({
      editService: Object.assign({}, editService, changeVal),
    });
  }

  getFormItemLayout = () =
> ( {
  labelCol: { span: 6 }
,
  wrapperCol: { span: 14 }
,
}

)
;

render()
{
  const {locale = {}} = this.props;
  const {isCreate, editService, editServiceDialogVisible, errors} = this.state;
  const {
    name,
    protectThreshold,
    groupName,
    metadataText,
    selector = {type: 'none'},
  } = editService;
  const formItemLayout = this.getFormItemLayout();
  return (
    < Dialog
  className = "service-detail-edit-dialog"
  title = {isCreate ? locale.createService : locale.updateService}
  visible = {editServiceDialogVisible}
  onOk = {() =
>
  this.onConfirm()
}
  onCancel = {() =
>
  this.hide()
}
  onClose = {() =
>
  this.hide()
}
>
<
  Form
  {...
    DIALOG_FORM_LAYOUT
  }
>
<
  Form.Item
  required = {isCreate}
  {...
    formItemLayout
  }
  label = {`${locale.serviceName}:`
}
  {...
    errors.name
  }
>
  {
    !isCreate ? (
      < p > {name} < /p>
  ) :
    (
    < Input
    value = {name}
    onChange = {name = > this.onChangeCluster({name})
  }
    />
  )
  }
<
  /Form.Item>
  < Form.Item
  required
  {...
    formItemLayout
  }
  label = {`${locale.protectThreshold}:`
}
  {...
    errors.protectThreshold
  }
>
<
  Input
  value = {protectThreshold}
  onChange = {protectThreshold = > this.onChangeCluster({protectThreshold})
}
  />
  < /Form.Item>
  < Form.Item
  {...
    formItemLayout
  }
  label = {`${locale.groupName}:`
}>
<
  Input
  defaultValue = {groupName}
  placeholder = "DEFAULT_GROUP"
  readOnly = {
  !isCreate
}
  onChange = {groupName = > this.onChangeCluster({groupName})
}
  />
  < /Form.Item>
  < Form.Item
  label = {`${locale.metadata}:`
}
  {...
    formItemLayout
  }
>
<
  MonacoEditor
  language = {'properties'}
  width = {'100%'}
  height = {200}
  value = {metadataText}
  onChange = {metadataText = > this.onChangeCluster({metadataText})
}
  />
  < /Form.Item>
  < Form.Item
  label = {`${locale.type}:`
}
  {...
    formItemLayout
  }
>
<
  Select
  className = "full-width"
  defaultValue = {selector.type}
  onChange = {type = > this.onChangeCluster({selector: {...selector, type}})
}
>
<
  Select.Option
  value = "label" > {locale.typeLabel} < /Select.Option>
    < Select.Option
  value = "none" > {locale.typeNone} < /Select.Option>
    < /Select>
    < /Form.Item>
  {
    selector.type === 'label' && (
    < Form.Item
    label = {`${locale.selector}:`
  }
    {...
      formItemLayout
    }
  >
  <
    Input.TextArea
    value = {selector.expression}
    onChange = {expression = >
      this.onChangeCluster({selector: {...selector, expression}})
  }
    />
    < /Form.Item>
  )
  }
<
  /Form>
  < /Dialog>
)
  ;
}
}

export default EditServiceDialog;
